package com.hjs.test.util;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;

public class RedissonTokenUtils {
    static String token;
    static AtomicInteger token_seq = new AtomicInteger(0);
    private static final String LOCK_TEST_KEY = "redisson:lock:test";
    public static String getToken(){
        if(Objects.isNull(token)){
            //RedissonClientHolder.getRedissonClient().getKeys().getKeys().forEach(System.out::println);
            RLock fairLock = RedissonClientHolder.getRedissonClient().getFairLock(LOCK_TEST_KEY);
            fairLock.lock();
            if(Objects.isNull(token)){
                generateToken();
            }
            fairLock.unlock();
        }
        return token;
    }

    private static void generateToken(){
        token = String.format("the-token-%d", token_seq.getAndIncrement());
    }

    static class RedissonClientHolder{
        static volatile RedissonClient redissonClient;
        private static RedissonClient getRedissonClient(){
            if(Objects.isNull(redissonClient)){
                synchronized (Object.class){
                    if(Objects.isNull(redissonClient)) {
                        Config config = new Config();
                        config.useSingleServer().setAddress("redis://127.0.0.1:6379");
                        redissonClient = Redisson.create(config);
                    }
                }

            }
            return redissonClient;
        }
    }

    public static void main(String[] args) {
        int threadCount = 100;
        CountDownLatch latch = new CountDownLatch(threadCount);
        for(int i=0;i<threadCount;i++){
            new Thread(() ->{
                latch.countDown();
                try {
                    latch.await();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println(getToken());
            }).start();
        }
    }
}
